import React, {useEffect, useState, useRef} from 'react';
import {Table, Pagination, Progress, Button} from 'antd';
import {PlusSquareOutlined, MinusSquareOutlined, QuestionCircleFilled} from '@ant-design/icons';
import shortid from 'shortid';
import {connect} from 'react-redux';
import {withRouter} from 'react-router-dom';

import renewBoard from '~/model/renewBoard';

import {groupSearch, fetchDownload} from '~/service/renew';
import {getReportRounds} from '~/utils/menu';
import {parsePercent} from '~/utils/number';
import {buildTip} from '../common';
import {removeList, processReduce, getMapNextKey} from './util';

import './index.styl';

// 数字列
const numberColumns = [
    'can_renewal_num_sum',
    'can_renewal_num_sum_new',
    'can_renewal_num_sum_old',
    'can_renewal_num_sum_late_1',
    'can_renewal_num_sum_late_2',
];
// 进度条列
const progressColumns = [
    '综续目标达成率-整体',
    '综续目标达成率-新学员',
    '综续目标达成率-老学员',
    '综续目标达成率-插1学员',
    '综续目标达成率-插2学员',
    '纯续目标达成率-整体',
    '纯续目标达成率-新学员',
    '纯续目标达成率-老学员',
    '纯续目标达成率-插1学员',
    '纯续目标达成率-插2学员',
];
// 中文列
const textColumns = ['学部排名', '大组长', '学部', '中心', '年级', '学科', '大组排名', '小组长'];

const defaultReduce = [];
const defaultPager = {
    pageNum: 1,
    pageSize: 10
};

function DTable(props) {
    // type string 区别大组，小组
    const {
        title,
        viewName,
        type,
        match: {params: {id}},
        domId = 'dtable',
        // 点击的回调
        filterClick,
        searchValue
    } = props;

    const [columns, setColumns] = useState([]);
    const [data, setData] = useState([]);
    const [total, setTotal] = useState();

    const [loading, setLoading] = useState(false);
    const [downLoading, setDownLoading] = useState(false);
    const pagerRef = useRef(defaultPager);

    // 默认树深度
    const maxDepth = type === 'big' ? 5 : 6;
    const fixed = type === 'big' ? 2 : 3;
    const stateRef = useRef({...searchValue});
    const getParams = () => {
        const {smallFilter, dimensionAndValues, sortRule} = searchValue;

        const params = {
            viewName,
            rowReduce: processReduce(stateRef.current.rowReduce || []),
            permissions: type === 'big' ? [] : smallFilter,
            pager: pagerRef.current,
            rounds: getReportRounds(Number(id)),
            dimensionAndValues,
            sortRule,
        };

        return params;
    };

    const search = (pPage = defaultPager) => {
        const param = {
            ...getParams(),
            pager: pPage,
        };
        setLoading(true);
        groupSearch(param).then(res => {
            if (res.code === 0) {
                const {result, columns} = res.data;

                // dId text 的映射，columns
                const map = new Map();
                for (const ele of columns) {
                    map.set(ele.dId, ele.text);
                }

                const newColumns = [];
                levelTraverse(result, newColumns, map, columns);
                // 添加排名
                processRank(newColumns);
                let col = processColumns(newColumns, map);
                col = col.map((ele, index) => {
                    // 进度条展示
                    if (progressColumns.includes(ele.title)) {
                        ele.render = text => (
                            <div style={{position: 'relative'}} className="department-progess">
                                <span style={{position: 'absolute', left: 8, top: '10%', zIndex: 1}}>
                                    {Number.isNaN(parseFloat(text)) ? '-' : text}
                                </span>
                                <Progress
                                    strokeWidth={30}
                                    showInfo={false}
                                    percent={parseFloat(text)}
                                    size="small"
                                    strokeColor="#1890ff"
                                />
                                {/* {text} */}
                            </div>
                        );
                        ele.width = 200;
                    }
                    else if (!textColumns.includes(ele.title)) {
                        ele.render = text => (
                            <div style={{padding: 8}}>
                                {Number.isNaN(parseFloat(text)) ? '-' : text}
                            </div>
                        );
                    }

                    // 该组件有bug，有聚合数据时，不支持固定列
                    if (index < fixed && !stateRef.current.rowReduce?.length) {
                        ele.fixed = 'left';
                    }

                    ele.width = 120;
                    return ele;
                });
                setColumns(col);

                const detail = buildDetailList(result);
                setData(detail);

                setTotal(res?.pager?.count);
            }
        })
            .finally(() => {
                setLoading(false);
            });
    };

    // 添加排名部分的表头
    function processRank(columns) {
        if (!columns.length) {
            return;
        }
        // list的横向需要过一遍，col都需要是1
        const list = columns[0].list.map(e => ({
            row: e.row,
            col: 1
        }));
        const rank1 = parseColumnObj('rank1', list);
        const rank2 = parseColumnObj('rank2', list);
        columns.unshift(rank1);

        if (type === 'small') {
            columns.unshift(rank2);
        }
    }

    // 转义 dId text
    function processColumns(columns, map) {
        return columns.map(entry => {
            const title = map.get(entry.title) || entry.title;
            // if (/^rank/.test(entry.title)) {
            //     title = buildTip(title);
            // }
            return {
                ...entry,
                title
            };
        });
    }

    // 层级遍历 组件列定义
    function levelTraverse(node, columns, map, originColumns) {
        if (node === null) {
            return;
        }
        let commonValues = [];

        const queue = [];
        // 单元格分布
        let levelList = [];

        queue.push(node);
        while (queue.length > 0) {
            const ele = queue.shift();
            // 处理节点
            if (ele.dId || ele.colSpan === 0) {
                let colSpan = 1;
                if (ele.colSpan === 0) {
                    colSpan = 0;
                }
                else if (ele.config.status === 1) {
                    colSpan = maxDepth - ele.depth + 1;
                }
                levelList.push({
                    row: ele.count,
                    col: colSpan,
                });

                if (ele.levelEnd || !ele.children && queue.length === 0) {
                    const column = parseColumnObj(ele.dId, levelList);
                    columns.push(column);
                    // reset tmp list
                    levelList = [];
                }

                // 尾部共同列
                if (Array.isArray(ele.values) && ele.values.length > 0) {
                    commonValues = ele.values;
                }
            }

            // 处理children与queue
            if (ele.children && ele.children.length > 0) {
                // queue追加 标识一层最后一个元素
                if (queue.length === 0) {
                    ele.children[ele.children.length - 1].levelEnd = true;
                }
                else {
                    const pre = queue[queue.length - 1];
                    const firstChild = ele.children[0];
                    if (pre.depth < firstChild.depth) {
                        pre.levelEnd = true;
                    }
                }
                queue.push(...ele.children);
            }
            else if (ele.depth < maxDepth && ele.dId) {

                // 无children,根据深度向后合并
                const child = {
                    depth: ele.depth + 1,
                    colSpan: 0,
                    count: ele.count,
                    dId: getMapNextKey(map, ele.dId)
                };
                const pre = queue[queue.length - 1];
                if (pre && pre.depth < child.depth) {
                    pre.levelEnd = true;
                }
                queue.push(child);
            }
        }

        // 有的时候，数据里的列会比实际要多，根据返回的result控制实际展示的
        const originColumnsDid = originColumns.map(item => item.dId);
        // 追加尾部values
        for (const ele of commonValues) {
            if (originColumnsDid.includes(ele.dId)) {
                columns.push({
                    title: `${ele.dId}`,
                    dataIndex: `${ele.dId}`,
                });
            }
        }
    }

    // 表格列定义
    function parseColumnObj(dId, list) {
        return {
            title: `${dId}`,
            dataIndex: `${dId}`,
            render: buildRenderFunc(list),
            list
        };
    }

    function buildRenderFunc(list) {
        // 纵向
        const rowList = [];
        // 横向
        const colList = [];
        for (const ele of list) {
            if (ele.row === 1) {
                rowList.push(ele.row);
            }
            else if (ele.row > 1) {
                rowList.push(ele.row);
                for (let i = ele.row; i > 1; i--) {
                    rowList.push(0);
                }
            }
        }

        // col， 纵向0 总跟上一个的横向一样
        let j = 0;
        const tmp = list.map(e => e.col);
        for (let i = 0; i < rowList.length; i++) {
            // row第一个总不是0
            if (rowList[i] === 0) {
                colList.push(tmp[j - 1]);
            }
            else {
                colList.push(tmp[j]);
                j++;
            }
        }

        return (value, row, index) => {
            // status判断 +-状态
            const display = displayAndAction(value, row);

            const object = {
                children: display,
                props: {},
            };

            if (rowList[index] === 0) {
                object.props.rowSpan = 0;
            }
            else if (rowList[index] > 1) {
                object.props.rowSpan = rowList[index];
            }

            // col
            if (colList[index] === 0) {
                object.props.colSpan = 0;
            }
            else if (colList[index] > 1) {
                object.props.colSpan = colList[index];
            }
            return object;
        };
    }

    // 深度遍历 组成明细
    function buildDetailList(node) {
        const result = [];
        // parent nodes
        const stack = [];
        preorderTraverse(node);
        return result;
        function preorderTraverse(node) {
            if (node === null) {
                return;
            }
            // depth check
            while (stack.length && stack[stack.length - 1].depth >= node.depth) {
                stack.pop();
            }
            // process
            if (node.children && node.children.length > 0) {
                stack.push(node);
            }
            else {
                if (!node.dId) {
                    return;
                }
                const rowObj = {
                    key: shortid.generate()
                };

                // parent
                for (let i = 0; i < stack.length; i++) {
                    const ele = stack[i];
                    // 这里的parents 用作点击时，传递父节点信息的参数
                    if (ele.dId) {
                        rowObj[ele.dId] = {
                            dId: ele.dId,
                            text: ele.text,
                            status: ele.config?.status,
                            parents: stack.filter((e, index) => e.dId && index < i)
                                .map(e => ({dId: e.dId, text: e.text}))
                        };
                    }
                }

                const {values, dId, text, depth, config: {status}} = node;
                // current
                rowObj[dId] = {
                    text,
                    status,
                    dId,
                    parents: stack.filter(e => e.dId).map(e => ({dId: e.dId, text: e.text}))
                };

                if (values?.length) {
                    for (let i = 0; i < values.length; i++) {
                        const ele = values[i];
                        if (numberColumns.includes(ele.dId)) {
                            rowObj[ele.dId] = ele.text;
                        }
                        else {
                            rowObj[ele.dId] = parsePercent(parseFloat(ele.text), 2);
                        }
                    }
                }

                // 排名信息
                // stack里的第一个是null，第二个保存了排名信息
                let rank;
                if (stack.length > 1) {
                    rank = stack[1].config.rank;
                }
                // 按最高的聚合了，stack为空
                else {
                    rank = node.config.rank;
                }
                if (rank.rank1) {
                    rowObj.rank1 = rank.rank1;
                }

                if (rank.rank2) {
                    rowObj.rank2 = rank.rank2;
                }

                result.push(rowObj);
            }

            if (Array.isArray(node.children)) {
                for (const ele of node.children) {
                    preorderTraverse(ele);
                }
            }
        }
    }

    // 单元格动作
    function displayAndAction(ele, row) {
        if (typeof ele === 'object') {
            return (
                <span className="func">
                    {ele.status === 2
                        ? (
                            <MinusSquareOutlined onClick={() => {
                                handleReduceClick(ele, row);
                            }}
                            />
                        )
                        : ''}
                    {ele.status === 1
                        ? (
                            <PlusSquareOutlined onClick={() => {
                                handleReduceClick(ele, row);
                            }}
                            />
                        )
                        : ''}
                    <span onClick={() => {
                        handleFilterClick(ele);
                    }}
                    >
                        {ele.text}
                    </span>
                </span>
            );
        }
        return ele;
    }

    // 关联筛选
    function handleFilterClick(ele) {
        const filter = [...ele.parents, {dId: ele.dId, text: ele.text}];

        // filter点击回调
        if (filterClick) {
            filterClick(filter, type === 'big');
        }
    }

    // 展开收起
    function handleReduceClick(ele, row) {
        const list = [...ele.parents, {dId: ele.dId, text: ele.text}].map(e => `${e.dId}$$${e.text}`);

        if (ele.status === 2) {
            // 收起
            const result = removeList(stateRef.current.rowReduce, list);
            result.push(list);
            stateRef.current.rowReduce = result;
            // 此处拿不到最新的pager，因为声明该方法的最初位置是在获取数据之后，不是页面渲染
            search(pagerRef.current);
        }
        else {
            // 展开
            const result = removeList(stateRef.current.rowReduce, list);
            stateRef.current.rowReduce = result;
            // 此处拿不到最新的pager，因为声明该方法的最初位置是在获取数据之后，不是页面渲染
            search(pagerRef.current);
        }
    }

    const pagerChange = (num, size) => {
        const pageNum = size !== pagerRef.current.pageSize ? 1 : num;
        const pPage = {
            pageNum,
            pageSize: size
        };
        search(pPage);
        pagerRef.current = pPage;
    };

    useEffect(() => {
        // 改变外部条件时，重置到第一页, handleType 指的是操作了大组长或者小组长
        if (type === 'big' && searchValue.handleType === 'big') {
            return;
        }
        if (searchValue.handleType === 'small') {
            return;
        }
        search(defaultPager);
        pagerRef.current = defaultPager;
        stateRef.current = {
            ...searchValue,
            rowReduce: stateRef.current.rowReduce || []
        };
    }, [searchValue]);

    const handleDownload = () => {
        const param = getParams();
        setDownLoading(true);
        fetchDownload(param, () => setDownLoading(false));
    };

    return (
        <div className="dynamicTable">
            <div className="title-container">
                <h2 id={domId}>
                    {title}
                </h2>
                {columns.length > 0 && (
                    <Button
                        type="primary"
                        onClick={handleDownload}
                        loading={downLoading}
                    >
                        下载
                    </Button>
                )}
            </div>
            {columns.length > 1 && (
                <>
                    <Table
                        size="small"
                        loading={loading}
                        columns={columns}
                        dataSource={data}
                        scroll={{x: 'max-content'}}
                        bordered
                        pagination={false}
                    />
                    <Pagination
                        className="dtPager"
                        showSizeChanger
                        size="small"
                        total={total}
                        current={pagerRef.current.pageNum}
                        defaultPageSize={10}
                        pageSize={pagerRef.current.pageSize}
                        onChange={pagerChange}
                        // onShowSizeChange={sizeChange}
                        // eslint-disable-next-line babel/camelcase
                        locale={{items_per_page: '组/页'}}
                    />
                </>
            )}
        </div>
    );
}

export default connect(s => s)(withRouter(DTable));
